package com.anti.modular.bus.housebill.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.druid.sql.visitor.functions.If;
import com.anti.commom.api.Result;
import com.anti.commom.core.utils.DecimalUtils;
import com.anti.core.context.login.LoginContextHolder;
import com.anti.core.utils.IdFlowingUtil;
import com.anti.jdbc.DBUtils;
import com.anti.jdbc.support.page.PageParam;
import com.anti.jdbc.support.page.PageResult;
import com.anti.commom.core.exception.BusinessException;
import com.anti.modular.bus.billrentadjustment.entity.BillRentAdjustment;
import com.anti.modular.bus.billrentadjustment.service.BillRentAdjustmentService;
import com.anti.modular.bus.billwater.entity.BillWater;
import com.anti.modular.bus.billwater.entity.BillWaterRoom;
import com.anti.modular.bus.billwater.service.BillWaterService;
import com.anti.modular.bus.billwaterdetail.entity.BillWaterDetail;
import com.anti.modular.bus.billwaterdetail.service.BillWaterDetailService;
import com.anti.modular.bus.busbasicsettings.entity.BusBasicSettings;
import com.anti.modular.bus.busbasicsettings.service.BusBasicSettingsService;
import com.anti.modular.bus.busprintsettings.result.BusPrintSettingsResult;
import com.anti.modular.bus.busprintsettings.service.BusPrintSettingsService;
import com.anti.modular.bus.busroom.service.BusRoomService;
import com.anti.modular.bus.housebill.entity.Cty;
import com.anti.modular.bus.housebill.entity.HouseBill;
import com.anti.modular.bus.housebill.entity.HouseBillExcel;
import com.anti.modular.bus.housebill.enums.HouseBillExceptionEnum;
import com.anti.modular.bus.housebill.param.HouseBillDtParam;
import com.anti.modular.bus.housebill.param.HouseBillParam;
import com.anti.modular.bus.housebill.result.*;
import com.anti.modular.bus.housebill.service.HouseBillService;
import com.anti.modular.bus.housebilldetail.entity.HouseBillDetail;
import com.anti.modular.bus.housebilldetail.result.HouseBillDetailResult;
import com.anti.modular.bus.housebilldetail.service.HouseBillDetailService;
import com.anti.modular.bus.houselease.entity.HouseLease;
import com.anti.modular.bus.houselease.param.HouseLeaseParam;
import com.anti.modular.bus.houselease.result.LeaseFurnitureShResult;
import com.anti.modular.bus.houselease.service.HouseLeaseService;
import com.anti.modular.bus.houselease.vo.TimeVo;
import com.anti.modular.bus.hydropowermeter.param.HydropowerMeterParam;
import com.anti.modular.bus.hydropowermeter.result.HydropowerMeterResult;
import com.anti.modular.bus.hydropowermeter.service.HydropowerMeterService;
import com.anti.modular.bus.leaseappraise.entity.LeaseAppraiseEntity;
import com.anti.modular.bus.roomexpenses.entity.LeaseExpenses;
import com.anti.modular.bus.roomexpenses.entity.RoomExpenses;
import com.anti.modular.bus.roomexpenses.service.LeaseExpensesService;
import com.anti.modular.bus.roomreservation.entity.RoomReservation;
import com.anti.modular.commonutils.CalculateQs;
import com.anti.modular.owner.ownerleasebill.result.OwnerLeaseNumResult;
import com.anti.modular.sys.auth.pojo.SysLoginUser;
import com.anti.modular.sys.user.entity.SysUser;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 账单service接口实现类
 *
 * @author anti
 * @date 2021-05-07 09:59:46
 */
@Service
public class HouseBillServiceImpl implements HouseBillService {
    @Resource
    DBUtils dbUtils;
    @Resource
    BillWaterService billWaterService;
    @Resource
    BillWaterDetailService billWaterDetailService;
    @Resource
    HouseLeaseService houseLeaseService;

    @Resource
    HouseBillDetailService houseBillDetailService;
    @Resource
    BusBasicSettingsService busBasicSettingsService;
    @Resource
    LeaseExpensesService leaseExpensesService;
    @Resource
    private BusPrintSettingsService busPrintSettingsService;
    @Resource
    private HydropowerMeterService hydropowerMeterService;
    @Resource
    BillRentAdjustmentService billRentAdjustmentService;

    @Resource
    HouseBillService houseBillService;

    @Override
    public HouseBill getById(HouseBillParam houseBillParam){
        String sql="select * from house_bill where id =? ";
        return dbUtils.get(sql,HouseBill.class,houseBillParam.getId());
    }

    @Override
    public HouseBill getByNowBillByLeaseId(Long id, int type) {
        StringBuilder sql=new StringBuilder("select * from house_bill where house_lease_id =? and status=0 and bill_status = 0");
        if (type ==1){
            sql.append(" and bill_type = 2");
        }else {
            sql.append(" and bill_type = 3");
        }
        return dbUtils.getFirst(sql.toString(),HouseBill.class,id);
    }

    @Override
    public PageResult page(PageParam pageParam,HouseBillParam houseBillParam) {
        StringBuilder sb=new StringBuilder("select a.*,b.room_name,b.name,(select SUM(amount) from house_bill_detail where house_bill_id = a.id) as total_amount from house_bill  a left JOIN house_lease b on  b.id= a.house_lease_id where 1=1 and a.status = 0 and  b.status = 0 ");
        ArrayList<Object> param = CollectionUtil.newArrayList();
        if (ObjectUtil.isNotNull(houseBillParam)) {
            // 根据賬單流水號 查询
            if (ObjectUtil.isNotEmpty(houseBillParam.getType())) {
                String type = houseBillParam.getType();
                if ("1".equals(type)){
                    sb.append(" and a.bill_status in (0,3)");
                    if (ObjectUtil.isNotEmpty(houseBillParam.getNumType())) {
                        int numType = houseBillParam.getNumType();
                        if (numType==1){
                            sb.append(" and DATE_FORMAT(a.rented_day,'%Y-%m-%d')<DATE_FORMAT(NOW(),'%Y-%m-%d')");
                        }else if (numType==2){
                            sb.append(" and DATE_FORMAT(a.rented_day,'%Y-%m-%d')=DATE_FORMAT(NOW(),'%Y-%m-%d')");
                        }else if (numType==3){
                            sb.append(" and  a.bill_status =3 ");
                        }
                    }
                }else {
                    sb.append(" and a.bill_status in (1,4)");
                }
            }
            // 根据賬單類型 （字典 bill_type） 查询
            if (ObjectUtil.isNotEmpty(houseBillParam.getBillType()) && houseBillParam.getBillType()!=0) {
               sb.append(" and a.bill_type = ?");
               param.add(houseBillParam.getBillType());
            }
            // 根据業主名稱 查询
            if (ObjectUtil.isNotEmpty(houseBillParam.getSearchType())&&ObjectUtil.isNotEmpty(houseBillParam.getSearchValue())) {
                String searchType = houseBillParam.getSearchType();
                if ("1".equals(searchType)||"2".equals(searchType)){
                    sb.append(" and a.house_lease_id in ( select id from  house_lease where room_name like ? )");
                    param.add("%"+houseBillParam.getSearchValue()+"%");
                }else if ("3".equals(searchType)){
                    sb.append(" and  a.house_lease_id in ( select id from  house_lease where name like ? ) ");
                    param.add("%"+houseBillParam.getSearchValue()+"%");
                }else if ("4".equals(searchType)){
                    sb.append(" and a.house_lease_id in ( select id from  house_lease where phone like ? ) ");
                    param.add(houseBillParam.getSearchValue()+"%");
                }
            }
        }
        sb.append(" order by a.create_time desc");
        PageResult query = dbUtils.query(pageParam, sb.toString(), HouseBillPageResult.class, param.toArray());
        List<HouseBillPageResult> houseBillResults = (List<HouseBillPageResult>) query.getData();
        List<Long> collectIds = houseBillResults.stream().map(x -> x.getId()).collect(Collectors.toList());
        if (collectIds.size()>0){
            String sql ="select * from house_bill_detail where house_bill_id in (:ids) and status = 0";
            HashMap<Object, Object> params = CollectionUtil.newHashMap();
            params.put("ids",collectIds);
            List<HouseBillDetailResult> houseBillDetails = dbUtils.query(sql, HouseBillDetailResult.class, params);
            for (int i = 0; i < houseBillResults.size(); i++) {
                HouseBillPageResult houseBillResult = houseBillResults.get(i);
                houseBillResult.setSubtotal(houseBillResult.getTotalAmount());
                List<HouseBillDetailResult> collect = houseBillDetails.stream().filter(a -> a.getHouseBillId().equals( houseBillResult.getId())).collect(Collectors.toList());
                houseBillResult.setDetails(collect);
                for (int i1 = 0; i1 < collect.size(); i1++) {
                    int rentAmountType = collect.get(i1).getRentAmountType();
                    if (rentAmountType ==1){
                        houseBillResult.setHyCb(1);
                        break;
                    }
                }
            }
        }
        query.setData(houseBillResults);
        return query;
    }

    @Override
    public PageResult analysispage(PageParam pageParam,HouseBillParam houseBillParam) {
        int numType = houseBillParam.getNumType();
        PageResult query=new PageResult();
        if(numType==3){//本月到期业主
            StringBuilder sb=new StringBuilder("select * from owner_lease where DATE_FORMAT(rent_end_date,'%Y-%m')<=DATE_FORMAT(NOW(),'%Y-%m') and lease_status <> 2");
            ArrayList<Object> param = CollectionUtil.newArrayList();
            sb.append(" order by create_time desc");
            return dbUtils.query(pageParam,sb.toString(),param.toArray());
        }if(numType==1){//本月到期租约
            StringBuilder sb=new StringBuilder("select * from house_lease where  status =0  and lease_status <> 2 and DATE_FORMAT(rent_end_date,'%Y-%m')<=DATE_FORMAT(NOW(),'%Y-%m')");
            ArrayList<Object> param = CollectionUtil.newArrayList();
            sb.append(" order by rent_end_date");
            return dbUtils.query(pageParam,sb.toString(),param.toArray());
        }else{
            StringBuilder sb=new StringBuilder("select a.*,b.room_name,b.name,(select SUM(amount) from house_bill_detail where house_bill_id = a.id) as total_amount from house_bill  a left JOIN house_lease b on  b.id= a.house_lease_id where 1=1 and a.status = 0 and  b.status = 0 ");
            ArrayList<Object> param = CollectionUtil.newArrayList();
            if (ObjectUtil.isNotNull(houseBillParam)) {
                // 根据賬單流水號 查询
                if (ObjectUtil.isNotEmpty(houseBillParam.getType())) {
                    String type = houseBillParam.getType();
                    if ("1".equals(type)){
                        if (ObjectUtil.isNotEmpty(houseBillParam.getNumType())) {
                            if (numType==0){
                                sb.append(" and  DATE_FORMAT(a.rented_day,'%Y-%m')<=DATE_FORMAT(NOW(),'%Y-%m') and a.id in (select house_bill_id from house_bill_detail where house_bill_id = a.id and bill_in_out_type=1) and a.bill_status in (0,3)");
                            }else if (numType==2){
                                sb.append(" and  DATE_FORMAT(a.rented_day,'%Y-%m')<=DATE_FORMAT(NOW(),'%Y-%m') and a.id in (select house_bill_id from house_bill_detail where house_bill_id = a.id and bill_in_out_type=2) and a.bill_status in (0,3) ");
                            }
                        }
                    }else {
                        sb.append(" and a.bill_status in (1,4)");
                    }
                }
            }
            sb.append(" order by a.create_time desc");
            query = dbUtils.query(pageParam, sb.toString(), HouseBillPageResult.class, param.toArray());
            List<HouseBillPageResult> houseBillResults = (List<HouseBillPageResult>) query.getData();
            List<Long> collectIds = houseBillResults.stream().map(x -> x.getId()).collect(Collectors.toList());
            if (collectIds.size()>0){
                String sql ="select * from house_bill_detail where house_bill_id in (:ids) and status = 0";
                HashMap<Object, Object> params = CollectionUtil.newHashMap();
                params.put("ids",collectIds);
                List<HouseBillDetailResult> houseBillDetails = dbUtils.query(sql, HouseBillDetailResult.class, params);
                for (int i = 0; i < houseBillResults.size(); i++) {
                    HouseBillPageResult houseBillResult = houseBillResults.get(i);
                    houseBillResult.setSubtotal(houseBillResult.getTotalAmount());
                    List<HouseBillDetailResult> collect = houseBillDetails.stream().filter(a -> a.getHouseBillId().longValue() == houseBillResult.getId().longValue()).collect(Collectors.toList());
                    houseBillResult.setDetails(collect);
                    for (int i1 = 0; i1 < collect.size(); i1++) {
                        int rentAmountType = collect.get(i1).getRentAmountType();
                        if (rentAmountType ==1){
                            houseBillResult.setHyCb(1);
                            break;
                        }
                    }
                }
            }
            query.setData(houseBillResults);
            return query;
        }
    }
    @Override
    public OwnerLeaseNumResult houseBillService(HouseBillParam houseBillParam) {
        StringBuilder sb=new StringBuilder("");
        if (ObjectUtil.isNotNull(houseBillParam)) {
            // 根据賬單類型 （字典 bill_type） 查询
            if (ObjectUtil.isNotEmpty(houseBillParam.getBillType())) {
                sb.append(" and bill_type = '"+houseBillParam.getBillType()+"'");
            }
            // 根据業主名稱 查询
            if (ObjectUtil.isNotEmpty(houseBillParam.getSearchType())&&ObjectUtil.isNotEmpty(houseBillParam.getSearchValue())) {
                String searchType = houseBillParam.getSearchType();
                if ("1".equals(searchType)||"2".equals(searchType)){
                    sb.append(" and house_lease_id in ( select id from  house_lease where room_name like '%"+houseBillParam.getSearchValue()+"%' )");
                }else if ("3".equals(searchType)){
                    sb.append(" and  house_lease_id in ( select id from  house_lease where name like '%"+houseBillParam.getSearchValue()+"%' ) ");
                }else if ("4".equals(searchType)){
                    sb.append(" and house_lease_id in ( select id from  house_lease where phone like '"+houseBillParam.getSearchValue()+"%' ) ");
                }
            }
        }
        String s = sb.toString();
        String sql="SELECT (select count(*) from house_bill where bill_status in (0,3) and status=0 "+s+") as all_num," +
                "(select count(*) from house_bill where bill_status in (0,3) and status=0 and DATE_FORMAT(rented_day,'%Y-%m-%d')<DATE_FORMAT(NOW(),'%Y-%m-%d') "+s+") as yq_num," +
                "(select count(*) from house_bill where bill_status in (0,3) and status=0 and DATE_FORMAT(rented_day,'%Y-%m-%d')=DATE_FORMAT(NOW(),'%Y-%m-%d') "+s+") as now_num," +
                "(select count(*) from house_bill where bill_status=3 and status=0 "+s+") as qs_num from DUAL";
        return dbUtils.getFirst(sql,OwnerLeaseNumResult.class);
    }

    @Override
    public List<HouseBillExcel> getExportData(HouseBillParam houseBillParam) {
        StringBuilder sb=new StringBuilder("SELECT a.*,(select name from bus_means_of_transaction where id =a.collection_type) as collectionTypeName, b.room_name,b. NAME,(SELECT SUM(amount)" +
                " FROM house_bill_detail WHERE house_bill_id = a.id ) AS total_amount FROM house_bill a LEFT JOIN house_lease b ON b.id = a.house_lease_id " +
                " WHERE  a. STATUS = 0 AND b. STATUS = 0 ");
        ArrayList<Object> param = CollectionUtil.newArrayList();
        if (ObjectUtil.isNotNull(houseBillParam)) {
            // 根据賬單流水號 查询
            if (ObjectUtil.isNotEmpty(houseBillParam.getType())) {
                String type = houseBillParam.getType();
                if ("1".equals(type)){
                    sb.append(" and a.bill_status in (0,3)");
                    if (ObjectUtil.isNotEmpty(houseBillParam.getNumType())) {
                        int numType = houseBillParam.getNumType();
                        if (numType==1){
                            sb.append(" and DATE_FORMAT(a.rented_day,'%Y-%m-%d')<DATE_FORMAT(NOW(),'%Y-%m-%d')");
                        }else if (numType==2){
                            sb.append(" and DATE_FORMAT(a.rented_day,'%Y-%m-%d')=DATE_FORMAT(NOW(),'%Y-%m-%d')");
                        }else if (numType==3){
                            sb.append(" and  a.bill_status =3 ");
                        }
                    }
                }else {
                    sb.append(" and a.bill_status in (1,4)");
                }
            }
            // 根据賬單類型 （字典 bill_type） 查询
            if (ObjectUtil.isNotEmpty(houseBillParam.getBillType())) {
                sb.append(" and a.bill_type = ?");
                param.add(houseBillParam.getBillType());
            }
            // 根据業主名稱 查询
            if (ObjectUtil.isNotEmpty(houseBillParam.getSearchType())&&ObjectUtil.isNotEmpty(houseBillParam.getSearchValue())) {
                String searchType = houseBillParam.getSearchType();
                if ("1".equals(searchType)||"2".equals(searchType)){
                    sb.append(" and a.house_lease_id in ( select id from  house_lease where room_name like ? )");
                    param.add("%"+houseBillParam.getSearchValue()+"%");
                }else if ("3".equals(searchType)){
                    sb.append(" and  a.house_lease_id in ( select id from  house_lease where name like ? ) ");
                    param.add("%"+houseBillParam.getSearchValue()+"%");
                }else if ("4".equals(searchType)){
                    sb.append(" and a.house_lease_id in ( select id from  house_lease where phone like ? ) ");
                    param.add(houseBillParam.getSearchValue()+"%");
                }
            }
        }
        sb.append(" order by a.create_time desc");
        List<HouseBillExcel> query = dbUtils.query(sb.toString(), HouseBillExcel.class, param.toArray());
        List<Long> collect = query.stream().map(item -> item.getId()).collect(Collectors.toList());
        if (collect.size()>0){
            String sql="select id,house_bill_id,rent_amount_name AS detailName,amount from house_bill_detail where status=0 and house_bill_id in (:ids)";
            HashMap<Object, Object> par = CollectionUtil.newHashMap();
            par.put("ids",collect);
            List<Cty> detailList = dbUtils.query(sql, Cty.class, par);
            for (int i = 0; i < query.size(); i++) {
                HouseBillExcel houseBillExcel = query.get(i);
                List<Cty> ctyList = detailList.stream().filter(item -> item.getHouseBillId().equals(houseBillExcel.getId())).collect(Collectors.toList());
                houseBillExcel.setDetailNameLs(ctyList);
            }
        }
        return query;
    }

    @Override
    public PageResult  houseBillPageByLeaseId(PageParam pageParam, HouseBillParam houseBillParam) {
        StringBuilder sb=new StringBuilder("select a.*,(select SUM(amount) from house_bill_detail where house_bill_id = a.id) as total_amount from house_bill a where 1=1 and a.status = 0 and a.house_lease_id =? order by create_time desc");
        PageResult query = dbUtils.query(pageParam, sb.toString(), HouseBillResult.class, houseBillParam.getHouseLeaseId());
        List<HouseBillResult> houseBillResults = (List<HouseBillResult>) query.getData();
        List<Long> collectIds = houseBillResults.stream().map(x -> x.getId()).collect(Collectors.toList());
        String sql ="select * from house_bill_detail where house_bill_id in (:ids) and status = 0";
        HashMap<Object, Object> param = CollectionUtil.newHashMap();
        param.put("ids",collectIds);
        List<HouseBillDetailResult> houseBillDetails = dbUtils.query(sql, HouseBillDetailResult.class, param);
        for (int i = 0; i < houseBillResults.size(); i++) {
            HouseBillResult houseBillResult = houseBillResults.get(i);
            houseBillResult.setSubtotal(houseBillResult.getTotalAmount());
            List<HouseBillDetailResult> collect = houseBillDetails.stream().filter(a -> a.getHouseBillId().equals(houseBillResult.getId())).collect(Collectors.toList());
            houseBillResult.setDetails(collect);
            for (int i1 = 0; i1 < collect.size(); i1++) {
                int rentAmountType = collect.get(i1).getRentAmountType();
                if (rentAmountType ==1){
                    houseBillResult.setHyCb(1);
                    break;
                }
            }
        }
        query.setData(houseBillResults);
        return query;
    }

    @Override
    public List<HouseBill> list(HouseBillParam houseBillParam) {
        String sql="";
        return dbUtils.query(sql,HouseBill.class);
    }

    @Override
    public void add(HouseBillParam houseBillParam) {
        HouseBill houseBill = new HouseBill();
        BeanUtil.copyProperties(houseBillParam, houseBill);
        dbUtils.insert(houseBill);
    }

    @Override
    public Long add(HouseBill houseBill) {
        String string = dbUtils.insertKey(houseBill).toString();
        long key = Long.parseLong(string);
        return key;
    }

    public void delete(HouseBillParam houseBillParam) {
        String sql="delete  from house_bill where id =? ";
        dbUtils.execSql(sql,houseBillParam.getId());
    }

    public void edit(HouseBillParam houseBillParam) {
        checkBillIsTc(houseBillParam.getId());
        HouseBill houseBill = this.queryHouseBill(houseBillParam);
        BeanUtil.copyProperties(houseBillParam, houseBill);
        dbUtils.update(houseBill);
    }

    @Override
    public void editDt(HouseBillDtParam houseBillParam) {
        Long billId = houseBillParam.getId();
        checkBillIsTc(billId);
        HouseBillParam houseBam=new HouseBillParam();
        houseBam.setId(billId);
        HouseBill byId = getById(houseBam);
        byId.setRemark(houseBillParam.getRemark());
        Date date = new Date();
        Long sysLoginUserId = LoginContextHolder.me().getSysLoginUserId();
        byId.setUpdateTime(date);
        byId.setUpdateUser(sysLoginUserId);
        dbUtils.update(byId);
        List<HouseBillDetail> sdtx = houseBillParam.getSdtx();
        String ypdateSql="update house_bill_detail set amount =? ,update_time=?,update_user=? where id =? ";
        for (int i = 0; i < sdtx.size(); i++) {
            HouseBillDetail houseBillDetail = sdtx.get(i);
            dbUtils.execSql(ypdateSql,houseBillDetail.getAmount(),date,sysLoginUserId,houseBillDetail.getId());
        }
        List<HouseBillDetail> lssr = houseBillParam.getLssr();
        houseBillDetailService.deleteByBillIdAndType(billId,4);
        for (int i = 0; i < lssr.size(); i++) {
            HouseBillDetail houseBillDetail = lssr.get(i);
            houseBillDetail.setId(null);
            houseBillDetail.setHouseBillId(billId);
            houseBillDetail.setBillInOutType(1);
            //押金 1  水電 2  3 （租金、4临时收入、5临时支出）
            houseBillDetail.setDepositHydropowerFlag(4);
            //費用類型（字典  1抄表 0不抄表） 抄表需要
            houseBillDetail.setRentAmountType(0);
            houseBillDetail.setStatus(0);
            houseBillDetail.setCreateTime(date);
            houseBillDetail.setCreateUser(sysLoginUserId);
            houseBillDetailService.add(houseBillDetail);
        }
        List<HouseBillDetail> lszc = houseBillParam.getLszc();
        houseBillDetailService.deleteByBillIdAndType(billId,5);
        for (int i = 0; i < lszc.size(); i++) {
            HouseBillDetail houseBillDetail = lszc.get(i);
            houseBillDetail.setId(null);
            houseBillDetail.setHouseBillId(billId);
            houseBillDetail.setBillInOutType(2);
            houseBillDetail.setAmount(houseBillDetail.getAmount().negate());
            //押金 1  水電 2  3 （租金、4临时收入、5临时支出）
            houseBillDetail.setDepositHydropowerFlag(5);
            //費用類型（字典  1抄表 0不抄表） 抄表需要
            houseBillDetail.setRentAmountType(0);
            houseBillDetail.setStatus(0);
            houseBillDetail.setCreateTime(date);
            houseBillDetail.setCreateUser(sysLoginUserId);
            houseBillDetailService.add(houseBillDetail);
        }
        int type = houseBillParam.getType();
        if(type == 2) {
            List<HouseBillDetail> yjList = houseBillParam.getYjList();
            HouseBillDetail houseBillDetail =null;
            for (int i = 0; i < yjList.size(); i++) {
                houseBillDetail = yjList.get(i);
                dbUtils.execSql(ypdateSql,houseBillDetail.getAmount().negate(),date,sysLoginUserId,houseBillDetail.getId());
            }
        }
        //判断当前是否是修改清算账单 增加家私损坏详情
        int billStatus = byId.getBillStatus();
        if (billStatus == 3){
            houseBillDetailService.deleteByBillIdAndType(billId,9);
            List<LeaseFurnitureShResult> jsshData = houseBillParam.getJsshData();
            for (int i = 0; i < jsshData.size(); i++) {
                LeaseFurnitureShResult leaseFurnitureShResult = jsshData.get(i);
                if (leaseFurnitureShResult.isSh()){
                    HouseBillDetail houseBillDetail = new HouseBillDetail();
                    houseBillDetail.setId(null);
                    houseBillDetail.setHouseBillId(billId);
                    houseBillDetail.setBillInOutType(1);
                    houseBillDetail.setRentAmountCategory(leaseFurnitureShResult.getId());
                    houseBillDetail.setRentAmountName(leaseFurnitureShResult.getName());
                    houseBillDetail.setAmount(leaseFurnitureShResult.getPcPrice());
                    //押金 1  水電 2  3 （租金、4临时收入、5临时支出）
                    houseBillDetail.setDepositHydropowerFlag(9);
                    //費用類型（字典  1抄表 0不抄表） 抄表需要
                    houseBillDetail.setRentAmountType(0);
                    houseBillDetail.setStatus(0);
                    houseBillDetail.setCreateTime(date);
                    houseBillDetail.setCreateUser(sysLoginUserId);
                    houseBillDetailService.add(houseBillDetail);
                }
            }
        }

    }

    /**
     * 拖欠
     * @param houseBillParam
     */
    @Override
    public void editTuoQian(HouseBillParam houseBillParam) {
        checkBillIsTc(houseBillParam.getId());
        HouseBill houseBill = this.queryHouseBill(houseBillParam);
        Date parse = DateUtil.parse(houseBillParam.getRentedDay(), "yyyy-MM-dd");
        houseBill.setRentedDay(parse);
        houseBill.setUpdateTime(new Date());
        houseBill.setUpdateUser(LoginContextHolder.me().getSysLoginUserId());
        dbUtils.update(houseBill);
    }

    /**
     * 到賬
     * @param houseBillParam
     */
    @Override
    public void editDaozang(HouseBillParam houseBillParam) {
        checkBillIsTc(houseBillParam.getId());
        HouseBill houseBill = this.queryHouseBill(houseBillParam);
        Date parse = DateUtil.parse(houseBillParam.getReceiveDate(), "yyyy-MM-dd");
        houseBill.setReceiveDate(parse);
        houseBill.setCollectionType(houseBillParam.getCollectionType());
        houseBill.setCollectionTypeName(houseBillParam.getCollectionTypeName());
        houseBill.setReceiveAmount(houseBillParam.getReceiveAmount());
        Date date = new Date();
        houseBill.setUpdateTime(date);
        Long sysLoginUserId = LoginContextHolder.me().getSysLoginUserId();
        houseBill.setUpdateUser(sysLoginUserId);
        houseBill.setBillStatus(1);
        BigDecimal xIaojiById = houseBillDetailService.getXIaojiById(houseBillParam.getId());
        houseBill.setSubtotal(xIaojiById);
        dbUtils.update(houseBill);
        // 保存定金流水表
        HouseLeaseParam houseLeaseParam=new HouseLeaseParam();
        houseLeaseParam.setId(houseBill.getHouseLeaseId());
        HouseLease houseLease = houseLeaseService.getById(houseLeaseParam);
        BillWater billWaterParam = getBillWaterParam(houseBill,houseLease,sysLoginUserId);
        Long billWaterKey = billWaterService.add(billWaterParam);
        //保存流水房間關聯表
        BillWaterRoom billWaterRoom=new BillWaterRoom();
        billWaterRoom.setBillWaterId(billWaterKey);
        billWaterRoom.setRoomId(houseLease.getRoomId());
        billWaterRoom.setRoomName(houseLease.getRoomName());
        billWaterRoom.setName(houseLease.getName());
        dbUtils.insert(billWaterRoom);
        // 保存定金流水詳情表
        List<HouseBillDetailResult> billDetail = houseBillDetailService.getListByIdWithNoXz(houseBill.getId());
        BillWaterDetail billWaterDetail=null;
        for (int i = 0; i < billDetail.size(); i++) {
            HouseBillDetailResult houseBillDetailResult = billDetail.get(i);
            billWaterDetail=new BillWaterDetail();
            billWaterDetail.setBillInOutType(houseBillDetailResult.getBillInOutType());
            billWaterDetail.setAmount(DecimalUtils.toBigDecimal(houseBillDetailResult.getAmount()));
            billWaterDetail.setBillWaterId(billWaterKey);
            billWaterDetail.setName(houseBillDetailResult.getRentAmountName());
            billWaterDetail.setStatus(0);
            billWaterDetail.setCreateUser(sysLoginUserId);
            billWaterDetail.setCreateTime(date);
            billWaterDetailService.add(billWaterDetail);
        }
        if(houseBill.getBillType()!=4){//4 为押金调整
            //生成下一個周期賬單
            addNextBill(houseBill.getHouseLeaseId(),houseBill);
        }
    }


    public void addNextBill(Long leaseId,HouseBill bill){
        HouseLease lease = houseLeaseService.getByLeaseId(leaseId);
        int hydropower = lease.getHydropower();
        Date rentEndDate = lease.getRentEndDate();
        int receiptFu = lease.getReceiptFu();
        int receiptYj = lease.getReceiptYj();
        Long pkMain = lease.getId();
        Date date = new Date();
        Long sysLoginUserId = LoginContextHolder.me().getSysLoginUserId();
        //基础设置
        BusBasicSettings one = busBasicSettingsService.getOne();
        //计算费用时月天数 （字典 0按固定30天算 1按月份实际天数
        int calculateStyle = one.getCalculateStyle();
        //账单金额取整 （字典 0关闭 1打开 小数点后四舍五入）
        int amount = one.getAmount();
        //账单收租日日 （字典 0提前  1 固定）
        int billEndType = lease.getBillEndType();
        //账单收租日提前几日
        Integer billEndTqData = lease.getBillEndTqData();
        //账单收租日固定几月（有正负）
        Integer billEndGdmonthData = lease.getBillEndGdmonthData();
        //账单收租日固定几日
        Integer billEndGddayData = lease.getBillEndGddayData();
        Date billRentEndDate = bill.getRentEndDate();
        boolean checkHasNextBill = checkHasNextBill(billRentEndDate, rentEndDate);
        if (!checkHasNextBill){
            return;
        }
        int qsnum = bill.getQsnum();
        int billType = bill.getBillType();
        Long preBillId = bill.getId();
        if (hydropower == 0){
            Date nextStartTime = getNextTime(DateUtil.format(billRentEndDate,"yyyy-MM-dd"));
            TimeVo timeVo = CalculateQs.calculateQsNext(nextStartTime,rentEndDate, receiptFu, receiptYj);
            HouseBill houseBill =new HouseBill();
            houseBill.setRentStartDate(timeVo.getStart());
            houseBill.setRentEndDate(timeVo.getEnd());
            int qs = qsnum+1;
            houseBill.setBillType(billType);
            houseBill.setQsnum(qs);
            houseBill.setQs("租金"+qs+"期");
            //添加账单总表
            Long billPk = houseLeaseService.addBillBysDNo("QYZDZJ",houseBill, lease, date, sysLoginUserId, pkMain, billEndType, billEndTqData, billEndGdmonthData, billEndGddayData);
            //获取调整记录
            BillRentAdjustment adjustAmountByLeaseIdOnQsNum = billRentAdjustmentService.getAdjustAmountByLeaseIdOnQsNum(lease.getId(), qs);
            BigDecimal relRent=adjustAmountByLeaseIdOnQsNum.getRent();
            //添加租金明细
            houseLeaseService.addZjDetailForOne(amount,relRent,calculateStyle,houseBill,lease, date, sysLoginUserId,billPk);
            //添加水电费用明细
            List<LeaseExpenses> leaseExpensesList = leaseExpensesService.getLeaseExpensesLeaseId(leaseId);
            houseLeaseService.addExpensesDetailForAllOne(qs,preBillId,lease,DateUtil.format(houseBill.getRentedDay(),"yyyy-MM-dd"),date, sysLoginUserId,leaseExpensesList,billPk);
        }else {
            Date nextStartTime = getNextTime(DateUtil.format(billRentEndDate,"yyyy-MM-dd"));
            int qs = qsnum+1;
            if (billType ==2) {
                //账单
                TimeVo timeVo = CalculateQs.calculateQsNext(nextStartTime, rentEndDate, receiptFu, receiptYj);
                HouseBill houseBill =new HouseBill();
                houseBill.setRentStartDate(timeVo.getStart());
                houseBill.setRentEndDate(timeVo.getEnd());
                houseBill.setBillType(billType);
                houseBill.setQsnum(qs);
                houseBill.setQs("租金"+qs+"期");
                Long billPk =  houseLeaseService.addBillBysDNo("QYZDZJ",houseBill,lease, date, sysLoginUserId, pkMain, billEndType, billEndTqData, billEndGdmonthData, billEndGddayData);
                //获取调整记录
                BillRentAdjustment adjustAmountByLeaseIdOnQsNum = billRentAdjustmentService.getAdjustAmountByLeaseIdOnQsNum(lease.getId(), qs);
                BigDecimal relRent=adjustAmountByLeaseIdOnQsNum.getRent();
                //添加租金明细
                houseLeaseService.addZjDetailForOne(amount,relRent,calculateStyle,houseBill,lease, date, sysLoginUserId,billPk);
                //添加水电费用明细
                List<LeaseExpenses> leaseExpensesList = leaseExpensesService.getLeaseExpensesLeaseIdAndType(leaseId,1);
                houseLeaseService.addExpensesDetailForAllOneByType(qs,preBillId,lease,DateUtil.format(houseBill.getRentedDay(),"yyyy-MM-dd"),date, sysLoginUserId,leaseExpensesList,billPk,0);
            } else if (billType == 3){
                //计算水电账单
                int hydropowercycle = lease.getHydropowercycle();
                TimeVo timeVo = CalculateQs.calculateQsNext(nextStartTime, rentEndDate, hydropowercycle, 2);
                HouseBill houseBillsd =new HouseBill();
                houseBillsd.setRentStartDate(timeVo.getStart());
                houseBillsd.setRentEndDate(timeVo.getEnd());
                houseBillsd.setQsnum(qs);
                houseBillsd.setQs("水電"+qs+"期");
                houseBillsd.setBillType(billType);
                Integer hydropowerBillEndType = lease.getHydropowerBillEndType();
                Integer hydropowerBillEndTqData = lease.getHydropowerBillEndTqData();
                Integer hydropowerBillEndGdmonthData = lease.getHydropowerBillEndGdmonthData();
                Integer hydropowerBillEndGddayData = lease.getHydropowerBillEndGddayData();
                Long billPkSd =  houseLeaseService.addBillBysDNo("QYZDSD",houseBillsd,lease, date, sysLoginUserId, pkMain,
                hydropowerBillEndType, hydropowerBillEndTqData, hydropowerBillEndGdmonthData, hydropowerBillEndGddayData);
                List<LeaseExpenses> leaseExpensesList = leaseExpensesService.getLeaseExpensesLeaseIdAndType(leaseId,0);
                houseLeaseService.addExpensesDetailForAllOneByType(qs,preBillId,lease,DateUtil.format(houseBillsd.getRentedDay(),"yyyy-MM-dd"),date, sysLoginUserId,leaseExpensesList,billPkSd,1);
            }
        }

    }

    public static boolean checkHasNextBill(Date start,Date end){
        int compare = DateUtil.compare(start, end);
        return compare<0;
    }
    public static Date getNextTime(String time){
        Date startTime1=null;
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        try {
            Date start = dateFormat.parse(time);
            Calendar tempStart = Calendar.getInstance();
            tempStart.setTime(start);
            start.getTime();
            tempStart.add(Calendar.DATE, 1);
            startTime1 = tempStart.getTime();
        } catch (ParseException e) {
            e.printStackTrace();
            throw new BusinessException(0,"服务出现异常！");
        }
        return startTime1;
    }

    /**
     * 撤銷到賬
     * @param houseBillParam
     */
    @Override
    public void editCheXiaoDaoZang(HouseBillParam houseBillParam) {
        checkBillIsTc(houseBillParam.getId());
        HouseBill houseBill = this.queryHouseBill(houseBillParam);
        if(houseBill.getBillType()==4){//押金调整撤销
            //删除账单及其详情
            delAllBillByBillId(houseBill.getId());
            //刪除流水及其詳情
            billWaterService.deleteAllByType(houseBill.getId(),"house_bill");
            //重新生成当前账单
            addNowBillYjtz(houseBill.getHouseLeaseId(),houseBill);
        }else{
            String sql="select count(*) from house_bill where  qsnum>? and status=0 and bill_status=1  and house_lease_id =? and bill_type=? and id <> ? ";
            int intValue = dbUtils.getIntValue(sql, houseBill.getQsnum(), houseBill.getHouseLeaseId(),houseBill.getBillType(),houseBillParam.getId());
            if (intValue>0){
                throw new BusinessException(0,"當前撤銷的不是最新的到賬賬單！");
            }
            //删除后续的未到账的账单
            String getSufBillSql="select * from house_bill where qsnum>? and status=0 and bill_status =0 and house_lease_id =? and bill_type=? ";
            List<HouseBill> query = dbUtils.query(getSufBillSql, HouseBill.class, houseBill.getQsnum(), houseBill.getHouseLeaseId(), houseBill.getBillType());
            for (int i = 0; i < query.size(); i++) {
                //删除账单及其详情
                delAllBillByBillId(query.get(i).getId());
                //刪除流水及其詳情
                billWaterService.deleteAllByType(query.get(i).getId(),"house_bill");
            }
            //删除账单及其详情
            delAllBillByBillId(houseBill.getId());
            //刪除流水及其詳情
            billWaterService.deleteAllByType(houseBill.getId(),"house_bill");
            //重新生成当前账单
            addNowBill(houseBill.getHouseLeaseId(),houseBill);
        }
    }


    /**
     * 退租清算
     * @param houseBillParam
     */
    @Override
    public void editQingSuan(HouseBillParam houseBillParam) {
        checkBillIsTc(houseBillParam.getId());

        HouseBill houseBill = this.queryHouseBill(houseBillParam);
        HouseLeaseParam houseLeaseParam=new HouseLeaseParam();
        houseLeaseParam.setId(houseBill.getHouseLeaseId());
        HouseLeaseParam houseLearam=new HouseLeaseParam();
        houseLearam.setId(houseBill.getHouseLeaseId());
        HouseLease houseLease = houseLeaseService.getById(houseLearam);
        houseLease.setLeaseStatus(2);
        //退租
        houseLeaseService.editTzQs(houseLeaseParam);
        //修改 租约账单
        Long sysLoginUserId = LoginContextHolder.me().getSysLoginUserId();
        Date date = new Date();
        houseBill.setUpdateUser(sysLoginUserId);
        houseBill.setUpdateTime(date);
        String receiveDate = houseBillParam.getReceiveDate();
        houseBill.setReceiveDate(DateUtil.parse(receiveDate,"yyyy-MM-dd"));
        houseBill.setCollectionType(houseBillParam.getCollectionType());
        BigDecimal xIaojiById = houseBillDetailService.getXIaojiById(houseBill.getId());
        houseBill.setReceiveAmount(xIaojiById);
        houseBill.setBillStatus(4);
        dbUtils.update(houseBill);
        // 保存定金流水表
        String updateRoom="update bus_room set lease=0 ,leaseid=null where leaseid=? and id=?";
        dbUtils.execSql(updateRoom,houseLease.getId(),houseLease.getRoomId());
        BillWater billWaterParam = getBillWaterParam(houseBill,houseLease,sysLoginUserId);
        Long billWaterKey = billWaterService.add(billWaterParam);
        //保存流水房間關聯表
        BillWaterRoom billWaterRoom=new BillWaterRoom();
        billWaterRoom.setBillWaterId(billWaterKey);
        billWaterRoom.setRoomId(houseLease.getRoomId());
        billWaterRoom.setRoomName(houseLease.getRoomName());
        billWaterRoom.setName(houseLease.getName());
        dbUtils.insert(billWaterRoom);
        // 保存定金流水詳情表
        List<HouseBillDetailResult> billDetail = houseBillDetailService.getListByIdWithNoXz(houseBill.getId());
        BillWaterDetail billWaterDetail=null;
        for (int i = 0; i < billDetail.size(); i++) {
            HouseBillDetailResult houseBillDetailResult = billDetail.get(i);
            billWaterDetail=new BillWaterDetail();
            billWaterDetail.setBillInOutType(houseBillDetailResult.getBillInOutType());
            billWaterDetail.setAmount(DecimalUtils.toBigDecimal(houseBillDetailResult.getAmount()));
            billWaterDetail.setBillWaterId(billWaterKey);
            billWaterDetail.setName(houseBillDetailResult.getRentAmountName());
            billWaterDetail.setStatus(0);
            billWaterDetail.setCreateUser(sysLoginUserId);
            billWaterDetail.setCreateTime(date);
            billWaterDetailService.add(billWaterDetail);
        }
        //保存评价
        LeaseAppraiseEntity leaseAppraiseEntity=new LeaseAppraiseEntity();
        leaseAppraiseEntity.setLeaseId(houseBill.getHouseLeaseId());
        leaseAppraiseEntity.setRemark(houseBillParam.getRemark());
        leaseAppraiseEntity.setScore(houseBillParam.getScore());
        leaseAppraiseEntity.setAppraise(houseBillParam.getAppraise());
        leaseAppraiseEntity.setStatus(0);
        leaseAppraiseEntity.setCreateUser(sysLoginUserId);
        leaseAppraiseEntity.setCreateTime(date);
        dbUtils.insert(leaseAppraiseEntity);
    }

   public void addNowBill(Long leaseId, HouseBill bill){
        HouseLease lease = houseLeaseService.getByLeaseId(leaseId);
        int hydropower = lease.getHydropower();
        Date rentEndDate = lease.getRentEndDate();
        int receiptFu = lease.getReceiptFu();
        int receiptYj = lease.getReceiptYj();
        Long pkMain = lease.getId();
        Date date = new Date();
        Long sysLoginUserId = LoginContextHolder.me().getSysLoginUserId();
        //基础设置
        BusBasicSettings one = busBasicSettingsService.getOne();
        //计算费用时月天数 （字典 0按固定30天算 1按月份实际天数
        int calculateStyle = one.getCalculateStyle();
        //账单金额取整 （字典 0关闭 1打开 小数点后四舍五入）
        int amount = one.getAmount();
        //账单收租日日 （字典 0提前  1 固定）
        int billEndType = lease.getBillEndType();
        //账单收租日提前几日
        Integer billEndTqData = lease.getBillEndTqData();
        //账单收租日固定几月（有正负）
        Integer billEndGdmonthData = lease.getBillEndGdmonthData();
        //账单收租日固定几日
        Integer billEndGddayData = lease.getBillEndGddayData();
        Date billRentEndDate = bill.getRentStartDate();
        boolean checkHasNextBill = checkHasNextBill(billRentEndDate, rentEndDate);
        if (!checkHasNextBill){
            return;
        }
        int qsnum = bill.getQsnum();
        int billType = bill.getBillType();
        Long preBillId = bill.getId();
        if (hydropower == 0){
            TimeVo timeVo = CalculateQs.calculateQsNext(billRentEndDate, rentEndDate, receiptFu, receiptYj);
            HouseBill houseBill =new HouseBill();
            houseBill.setRentStartDate(timeVo.getStart());
            houseBill.setRentEndDate(timeVo.getEnd());
            int qs = qsnum;
            houseBill.setBillType(billType);
            houseBill.setQsnum(qs);
            houseBill.setQs("租金"+qs+"期");
            //添加账单总表
            Long billPk = houseLeaseService.addBillBysDNo("QYZDZJ",houseBill, lease, date, sysLoginUserId, pkMain, billEndType, billEndTqData, billEndGdmonthData, billEndGddayData);
            //获取调整记录
            BillRentAdjustment adjustAmountByLeaseIdOnQsNum = billRentAdjustmentService.getAdjustAmountByLeaseIdOnQsNum(lease.getId(), qs);
            BigDecimal relRent=adjustAmountByLeaseIdOnQsNum.getRent();
            //添加租金明细
            houseLeaseService.addZjDetailForOne(amount,relRent,calculateStyle,houseBill,lease, date, sysLoginUserId,billPk);
            //添加水电费用明细
            List<LeaseExpenses> leaseExpensesList = leaseExpensesService.getLeaseExpensesLeaseId(leaseId);
            houseLeaseService.addExpensesDetailForAllOne(qs,preBillId,lease,DateUtil.format(houseBill.getRentedDay(),"yyyy-MM-dd"),date, sysLoginUserId,leaseExpensesList,billPk);
            if(qs==1){
                //恢复定金及押金
                addDyBillByBillId(preBillId,billPk);
            }
        }else {
            int qs = qsnum;
            if (billType ==2) {
                //账单
                TimeVo timeVo  = CalculateQs.calculateQsNext(billRentEndDate, rentEndDate, receiptFu, receiptYj);
                HouseBill houseBill =new HouseBill();
                houseBill.setRentStartDate(timeVo.getStart());
                houseBill.setRentEndDate(timeVo.getEnd());
                houseBill.setBillType(billType);
                houseBill.setQsnum(qs);
                houseBill.setQs("租金"+qs+"期");
                Long billPk =  houseLeaseService.addBillBysDNo("QYZDZJ",houseBill,lease, date, sysLoginUserId, pkMain, billEndType, billEndTqData, billEndGdmonthData, billEndGddayData);
                //获取调整记录
                BillRentAdjustment adjustAmountByLeaseIdOnQsNum = billRentAdjustmentService.getAdjustAmountByLeaseIdOnQsNum(lease.getId(), qs);
                BigDecimal relRent=adjustAmountByLeaseIdOnQsNum.getRent();
                //添加租金明细
                houseLeaseService.addZjDetailForOne(amount,relRent,calculateStyle,houseBill,lease, date, sysLoginUserId,billPk);
                //添加水电费用明细
                List<LeaseExpenses> leaseExpensesList = leaseExpensesService.getLeaseExpensesLeaseIdAndType(leaseId,1);
                houseLeaseService.addExpensesDetailForAllOneByType(qs,preBillId,lease,DateUtil.format(houseBill.getRentedDay(),"yyyy-MM-dd"),date, sysLoginUserId,leaseExpensesList,billPk,0);
                if(qs==1){
                    //恢复定金及押金
                    addDyBillByBillId(preBillId,billPk);
                }
            } else if (billType == 3){
                //计算水电账单
                int hydropowercycle = lease.getHydropowercycle();
                TimeVo timeVo = CalculateQs.calculateQsNext(billRentEndDate, rentEndDate, hydropowercycle, 2);
                HouseBill houseBillsd =new HouseBill();
                houseBillsd.setRentStartDate(timeVo.getStart());
                houseBillsd.setRentEndDate(timeVo.getEnd());
                houseBillsd.setQsnum(qs);
                houseBillsd.setQs("水電"+qs+"期");
                houseBillsd.setBillType(billType);
                Integer hydropowerBillEndType = lease.getHydropowerBillEndType();
                Integer hydropowerBillEndTqData = lease.getHydropowerBillEndTqData();
                Integer hydropowerBillEndGdmonthData = lease.getHydropowerBillEndGdmonthData();
                Integer hydropowerBillEndGddayData = lease.getHydropowerBillEndGddayData();
                Long billPkSd =  houseLeaseService.addBillBysDNo("QYZDSD",houseBillsd,lease, date, sysLoginUserId, pkMain,
                        hydropowerBillEndType, hydropowerBillEndTqData, hydropowerBillEndGdmonthData, hydropowerBillEndGddayData);
                List<LeaseExpenses> leaseExpensesList = leaseExpensesService.getLeaseExpensesLeaseIdAndType(leaseId,0);
                houseLeaseService.addExpensesDetailForAllOneByType(qs,preBillId,lease,DateUtil.format(houseBillsd.getRentedDay(),"yyyy-MM-dd"),date, sysLoginUserId,leaseExpensesList,billPkSd,1);
            }
        }

    }

    public void addNowBillYjtz(Long leaseId, HouseBill bill){
        Long sysLoginUserId = LoginContextHolder.me().getSysLoginUserId();
        HouseBill houseBill=new HouseBill();
        houseBill.setQs("押金調整");
        houseBill.setBillType(4);//押金账单
        String snowflakesId = IdFlowingUtil.getSnowflakesId("QYZDZJ");
        houseBill.setHouseLeaseId(leaseId);
        houseBill.setNo(snowflakesId);
        houseBill.setSubtotal(bill.getSubtotal());
        houseBill.setBillStatus(0);
        //才有效
        houseBill.setStatus(0);
        houseBill.setCreateTime(new Date());
        houseBill.setCreateUser(sysLoginUserId);
        Long billPk = houseBillService.add(houseBill);
        HouseBillDetail houseBillDetail=new HouseBillDetail();
        if(houseBill.getSubtotal().signum()==1){//涨
            houseBillDetail.setBillInOutType(1);
            houseBillDetail.setAmount(bill.getSubtotal());
        }else {
            houseBillDetail.setBillInOutType(2);
            houseBillDetail.setAmount(bill.getSubtotal());
        }
        houseBillDetail.setRentAmountName("房屋押金");
        houseBillDetail.setDepositHydropowerFlag(1);
        houseBillDetail.setHouseBillId(billPk);
        houseBillDetail.setRentAmountType(0);
        houseBillDetail.setStatus(0);
        houseBillDetail.setCreateTime(new Date());
        houseBillDetail.setCreateUser(sysLoginUserId);
        houseBillDetailService.add(houseBillDetail);

    }
    public void delAllBillByBillId(Long billId){
        Date date = new Date();
        Long sysLoginUserId = LoginContextHolder.me().getSysLoginUserId();
        String detail="update house_bill_detail set status=2,update_time=?,update_user=? where house_bill_id in (select id from house_bill where  id=? and status=0)";
        dbUtils.execSql(detail,date,sysLoginUserId,billId);
        String main="update house_bill set status=2,update_time=?,update_user=? where id=? and status=0";
        dbUtils.execSql(main,date,sysLoginUserId,billId);
        String sql="delete from hydropower_meter where house_bill_id = ?";
        dbUtils.execSql(sql,billId);
    }
    public void addDyBillByBillId(Long billId,Long billPk){
        Date date = new Date();
        Long sysLoginUserId = LoginContextHolder.me().getSysLoginUserId();
        String detail="update house_bill_detail set status=0,update_time=?,update_user=? ,house_bill_id=? where house_bill_id =? and status=2 and  deposit_hydropower_flag in (1,6)";
        dbUtils.execSql(detail,date,sysLoginUserId,billPk,billId);
    }

    @Override
    public void delZjBillByBillId(Long billId) {
        String detail="delete  from  house_bill_detail  where house_bill_id =? and deposit_hydropower_flag = 3";
        dbUtils.execSql(detail,billId);
    }

    @Override
    public HouseBill detail(HouseBillParam houseBillParam) {
        return this.queryHouseBill(houseBillParam);
    }

    @Override
    public BillPringResult getPrintMsgForBill(Long id) {
        String sql="select * from house_bill where id=?";
        BillPringResult first = dbUtils.getFirst(sql, BillPringResult.class, id);
        BusPrintSettingsResult detail = busPrintSettingsService.detail();
        first.setMainTitle(detail.getLetterhead());
        first.setPayee(detail.getPayee());
        String shb="";
        int billStatus = first.getBillStatus();
        int billType = first.getBillType();
        //水電
        if (billType == 3) {
            if (billStatus == 1){
                shb="水電收款通知單";
            }else {
                shb="水電收據";
            }
        }else {
            if (billStatus == 1){
                shb="租金收款通知單";
            }else {
                shb="租金收據";
            }
        }
        first.setSubheading(shb);
        String sqfl="select * from house_lease where id =?";
        HouseLease lease = dbUtils.getFirst(sqfl, HouseLease.class, first.getHouseLeaseId());
        first.setZhuhu(lease.getRoomName()+"-"+lease.getName());
        BigDecimal xIaojiById = houseBillDetailService.getXIaojiById(first.getId());
        first.setSubtotal(xIaojiById);
        List<HouseBillDetail> noCbListById = houseBillDetailService.getNoCbListById(first.getId());
        first.setFeiList(noCbListById);
        HydropowerMeterParam hydropowerMeterParam=new HydropowerMeterParam();
        hydropowerMeterParam.setHouseBillId(first.getId());
        hydropowerMeterParam.setHouseLeaseId(first.getHouseLeaseId());
        List<HydropowerMeterResult> sdFyListByDetail = hydropowerMeterService.getSdFyListByDetail(hydropowerMeterParam);
        first.setCbList(sdFyListByDetail);
        return first;
    }

    @Override
    public List<HouseBillPlanList> getBillListByLeaseId(Long id) {
        List<HouseBillPlanList> res=new ArrayList<>();
        HouseLease lease = houseLeaseService.getByLeaseId(id);
        Integer receiptFu = lease.getReceiptFu();
        Integer receiptYj = lease.getReceiptYj();
        Date rentEndDate = lease.getRentEndDate();
        HouseBill bill = getByNowBillByLeaseId(id, 1);
        int qsnum = bill.getQsnum();
        Date rentEndDate1 = bill.getRentEndDate();
        int compare = DateUtil.compare(rentEndDate1,rentEndDate);
        if (compare==0){
            return res;
        }
        int relQsNum=1;
        Date dateStartTime = bill.getRentStartDate();
        if (qsnum==1){
            dateStartTime = DateUtil.offsetDay(rentEndDate1, 1);
            relQsNum = 1;
        }else {
            relQsNum=qsnum-1;
        }
        List<TimeVo> timeVos = CalculateQs.calculateQs(dateStartTime, rentEndDate, receiptFu, receiptYj);
        HouseBillPlanList billPlanList=null;
        for (int i = 0; i < timeVos.size(); i++) {
            relQsNum = relQsNum+1;
            TimeVo timeVo = timeVos.get(i);
            billPlanList=new HouseBillPlanList();
            billPlanList.setQsNum(relQsNum);
            billPlanList.setName(relQsNum+"期 "+DateUtil.format(timeVo.getStart(),"yyyy-MM-dd"));
            billPlanList.setRentStartDate(timeVo.getStart());
            billPlanList.setRentEndDate(timeVo.getEnd());
            res.add(billPlanList);
        }
        List<BillRentAdjustment> adjustmentListByLeaseId = billRentAdjustmentService.getAdjustmentListByLeaseId(id);
        for (int i = 0; i < adjustmentListByLeaseId.size(); i++) {
            BillRentAdjustment billRentAdjustment = adjustmentListByLeaseId.get(i);
            int qsnum1 = billRentAdjustment.getQsNum();
            for (int i1 = 0; i1 < res.size(); i1++) {
                HouseBillPlanList billPlanList1 = res.get(i1);
                int qsNum = billPlanList1.getQsNum();
                if (qsnum1==qsNum){
                    billPlanList1.setDisabled(true);
                }
            }
        }
        return res;
    }

    @Override
    public HouseBillWaterResult getWaterBillById(Long id) {
        String sql="select a.*,b.name,b.phone,b.room_name from house_bill a LEFT JOIN house_lease b on a.house_lease_id=b.id where a.id =?";
        HouseBillWaterResult first = dbUtils.getFirst(sql, HouseBillWaterResult.class, id);
        SysUser user = dbUtils.getFirst("SELECT * FROM sys_user WHERE id=?", SysUser.class, first.getUpdateUser());
        first.setUserName(user.getName());
       // 1押金   2水電   3 租金
        List<HouseBillDetail> fyxx = houseBillDetailService.getListByIdAndType(id, 1);
        first.setFyxx(fyxx);
        List<HouseBillDetail> lssr = houseBillDetailService.getListByIdAndType(id, 2);
        first.setLssr(lssr);
        List<HouseBillDetail> lszc = houseBillDetailService.getListByIdAndType(id, 3);
        first.setLszc(lszc);
        return first;
    }

    void checkBillIsTc(Long billId){
        String sql="select count(*) from house_lease where id = (select house_lease_id from house_bill where id =? ) and lease_status = 2 and status=0 ";
        int intValue = dbUtils.getIntValue(sql, billId);
        if (intValue>0){
            throw new BusinessException(0,"該租約已退租不允許修改！");
        }
    }
    /**
     * 获取账单
     *
     * @author anti
     * @date 2021-05-07 09:59:46
     */
    private HouseBill queryHouseBill(HouseBillParam houseBillParam) {
        HouseBill houseBill = this.getById(houseBillParam);
        if (ObjectUtil.isNull(houseBill)) {
            throw new BusinessException(HouseBillExceptionEnum.NOT_EXIST);
        }
        return houseBill;
    }

    private BillWater getBillWaterParam(HouseBill houseBill,HouseLease houseLease, Long sysLoginUserId ) {
        BillWater billWaterParam =new BillWater();
        billWaterParam.setRoomName(houseLease.getRoomName());
        billWaterParam.setName(houseLease.getName());
        billWaterParam.setSource(1);
        billWaterParam.setAmount(houseBill.getReceiveAmount());
        billWaterParam.setReceiveDate(houseBill.getReceiveDate());
        billWaterParam.setShouldReceiveDate(houseBill.getShouldReceiveDate());
        Date date = new Date();
        billWaterParam.setOperatingDate(date);
        billWaterParam.setTransaction(houseBill.getCollectionType());
        billWaterParam.setTransactionName(houseBill.getCollectionTypeName());
        SysLoginUser sysLoginUser = LoginContextHolder.me().getSysLoginUser();
        billWaterParam.setManagerId(houseBill.getCreateUser());
        billWaterParam.setManager(sysLoginUser.getName());
        billWaterParam.setManagertTime(houseBill.getUpdateTime());
        billWaterParam.setAuditFlag(0);
        billWaterParam.setNo(houseBill.getNo());
        if(houseBill.getReceiveAmount().signum()==1){//正金额
            billWaterParam.setBillInOutType(1);
        }else {
            billWaterParam.setBillInOutType(2);
        }
        billWaterParam.setBillId(houseBill.getId());
        billWaterParam.setBillTable("house_bill");
        billWaterParam.setStatus(0);
        billWaterParam.setCreateUser(sysLoginUserId);
        billWaterParam.setCreateTime(date);
        return billWaterParam;
    }

}
